#!/usr/bin/env julia
"""
Build Custom Julia System Image for GSICoreAnalysis.jl

This script creates a precompiled system image that significantly reduces
Julia startup time and JIT compilation overhead for GSI analysis.

Expected speedup: 5-10× faster startup, 2-3× faster first execution

Usage:
    julia build_sysimage.jl [OPTIONS]

Options:
    --output FILE       Output system image file (default: GSICoreAnalysis.so)
    --precompile FILE   Additional precompile script
    --cpu-target STRING CPU target (default: native)
    --verbose           Show verbose output
    --help              Show this help
"""

using Pkg

Pkg.activate(@__DIR__)
Pkg.instantiate()

println("="^80)
println("Julia GSI System Image Builder")
println("="^80)
println()

# Check if PackageCompiler is installed
using PackageCompiler
println("✓ PackageCompiler.jl available")

# Parse command line arguments
function parse_args(args)
    config = Dict{String,Any}(
        "output" => "GSICoreAnalysis.so",
        "precompile_file" => nothing,
        "cpu_target" => "native",
        "verbose" => false
    )

    i = 1
    while i <= length(args)
        arg = args[i]
        if arg == "--output" && i < length(args)
            config["output"] = args[i+1]
            i += 2
        elseif arg == "--precompile" && i < length(args)
            config["precompile_file"] = args[i+1]
            i += 2
        elseif arg == "--cpu-target" && i < length(args)
            config["cpu_target"] = args[i+1]
            i += 2
        elseif arg == "--verbose"
            config["verbose"] = true
            i += 1
        elseif arg == "--help"
            println(__doc__)
            exit(0)
        else
            @warn "Unknown argument: $arg"
            i += 1
        end
    end

    return config
end

config = parse_args(ARGS)

println("Configuration:")
println("  Output file: $(config["output"])")
println("  CPU target: $(config["cpu_target"])")
println("  Verbose: $(config["verbose"])")
println()

# Create precompilation script
precompile_script = """
# Precompilation script for GSICoreAnalysis.jl
println("Running precompilation for GSICoreAnalysis.jl...")

# Add project to load path
push!(LOAD_PATH, @__DIR__)

# Core modules
using LinearAlgebra
using Statistics
using Dates
using Printf
using SparseArrays

# Try to load GSICoreAnalysis if available
try
    using GSICoreAnalysis

    # Test basic functionality
    println("  ✓ GSICoreAnalysis loaded")

    # Create small test case to trigger compilation
    try
        config = AnalysisConfig(
            grid_size = (10, 10, 5),
            ensemble_size = 5,
            max_iterations = 10
        )
        println("  ✓ AnalysisConfig created")

        # Create state vector
        state_vector = GSICoreAnalysis.StateVectors.StateVector(config)
        println("  ✓ StateVector created")

        # Create control vector
        control_vector = GSICoreAnalysis.ControlVectors.ControlVector(config)
        println("  ✓ ControlVector created")

    catch e
        println("  ⚠ Could not run full test: \$e")
    end

catch e
    println("  ⚠ GSICoreAnalysis not loadable: \$e")
    println("  Continuing with base Julia compilation...")
end

# Common scientific computing packages
packages_to_load = [
    "NCDatasets",
    "Plots",
    "StatsPlots"
]

for pkg in packages_to_load
    try
        eval(Meta.parse("using \$pkg"))
        println("  ✓ \$pkg loaded")
    catch
        println("  ⚠ \$pkg not available (will not be precompiled)")
    end
end

println("Precompilation complete!")
"""

# Write precompilation script
precompile_file = config["precompile_file"]
if precompile_file === nothing
    precompile_file = tempname() * ".jl"
    write(precompile_file, precompile_script)
    println("✓ Precompilation script created: $precompile_file")
else
    println("✓ Using custom precompile script: $precompile_file")
end

# Build system image
println()
println("="^80)
println("Building System Image")
println("="^80)
println()
println("This may take 5-10 minutes...")
println("CPU target: $(config["cpu_target"])")
println()

try
    create_sysimage(
        precompile_execution_file=precompile_file,
        sysimage_path=config["output"],
        cpu_target=config["cpu_target"]
    )

    println()
    println("="^80)
    println("✓ System Image Built Successfully!")
    println("="^80)
    println()
    println("Output: $(config["output"])")

    # Get file size
    if isfile(config["output"])
        filesize_mb = filesize(config["output"]) / 1024 / 1024
        println("Size: $(round(filesize_mb, digits=2)) MB")
    end

    println()
    println("Usage:")
    println("  julia --sysimage=$(config["output"]) your_script.jl")
    println()
    println("Example:")
    println("  julia --sysimage=$(config["output"]) demos/operational_gsi_analysis.jl")
    println()
    println("Expected speedup:")
    println("  • Startup time: 5-10× faster")
    println("  • First execution: 2-3× faster")
    println("  • Overall workflow: 2-4× faster")
    println()

catch e
    println()
    println("="^80)
    println("✗ System Image Build Failed")
    println("="^80)
    println()
    println("Error: $e")
    println()
    println("Troubleshooting:")
    println("  1. Ensure PackageCompiler.jl is properly installed")
    println("  2. Check that all dependencies are installed")
    println("  3. Try with --verbose flag for more details")
    println("  4. Consider using a simpler precompile script")
    println()
    exit(1)
end

# Clean up temporary precompile file
if config["precompile_file"] === nothing
    rm(precompile_file, force=true)
end
